/*
 * To change this template, choose Tools | Templates and open the template in
 * the editor.
 */
package MainPackage;

import java.io.IOException;
import java.util.Random;
import java.util.Timer;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.TiledLayer;
import javax.microedition.media.MediaException;

public class MyGameCanvas extends GameCanvas implements Runnable {

    Image coupleImg;
    // Tọa độ điểm ảnh
    private int coupleX;
    private int coupleY;
    // Khoảng cách dịch chuyển ảnh
    private int dx = 1;
    private int dy = 1;
    // Trung tâm của màn hình
    public final int CENTER_X = getWidth() / 2;
    public final int CENTER_Y = getHeight() / 2;
    public static final int GAME_WIDTH = 160;
    public static final int GAME_HEIGHT = 160;
    public final int GAME_ORIGIN_X = (getWidth() - GAME_WIDTH) / 2;
    public final int GAME_ORIGIN_Y = (getHeight() - GAME_HEIGHT) / 2;
    public final int SECTION_HEIGHT = 64;
    public final int BASE = GAME_ORIGIN_Y + GAME_HEIGHT - SECTION_HEIGHT;
    public final int MAX_HEIGHT = 32;
    private boolean up = true;
    private boolean left = true;
    private int jumpHeight = MAX_HEIGHT;
    public Random random = new Random();
    Image backgroundImg;
    TiledLayer background;
    Sprite sp;
    CarSprite car;
    LayerManager manager;

    public MyGameCanvas() throws IOException {
        super(true);
        start();
    }
    public LayerManager getManager()
    {
        return manager;
    }
    public void start() throws IOException {
        manager = new LayerManager();
        try {
            coupleImg = Image.createImage("/Images/CoupleImage.png");
            sp = new Sprite(coupleImg, 10, 10);
            sp.defineReferencePixel(sp.getWidth() / 2, sp.getHeight());
            manager.append(sp);
            coupleX = CENTER_X;
            coupleY = CENTER_Y;
        } catch (IOException ioex) {
            System.err.println(ioex);
        }
        Thread runner = new Thread(this);
        runner.start();
        createBackground();
        
        manager.append(background);
        
        car = new CarSprite(this);
        car.start();
    }
    boolean stop = true;
    Clock clock;

    public void run() {
        Graphics g = getGraphics();
        clock = new Clock(15);
        new Timer().schedule(clock, 0, 1000);
        while (stop) {
            try {
                verifyGameState();
            } catch (IOException ex) {
            } catch (MediaException ex) {
            }
            checkUserInput();
            updateGameScreen(g);
            try {
                Thread.currentThread().sleep(30);
            } catch (Exception e) {
            }
        }
        showGameScore(g);
    }

    private void verifyGameState() throws IOException, MediaException {
        if (clock.getTimeLeft() == 0) {
            stop = false;
            return;
        }
        car.checkForColision();
    }

    private void checkUserInput() {
        int keyState = getKeyStates();
        calculateCoupleX(keyState);
        calculateCouple_X(keyState);
        //calculateCoupleY(keyState);
        //calculateCoupleY_1();
    }

    private void updateGameScreen(Graphics g) {
        g.setColor(0xffffff);
        g.fillRect(0, 0, getWidth(), getHeight());
        buildGameScreen(g);
        //g.drawImage( coupleImg, coupleX, coupleY, Graphics.HCENTER | Graphics.BOTTOM);

        sp.nextFrame();
        sp.setRefPixelPosition(coupleX, coupleY);
        //sp.paint(g);
        manager.paint(g, 0, 0);
        showTimeLeft(g);
        flushGraphics();
    }

    private void showTimeLeft(Graphics g) {
        String s = "Time Left: ";
        int timeLeft = clock.getTimeLeft();
        if (timeLeft <8) {
            if ((timeLeft % 2) == 0) {
                g.setColor(0xff0000);
            } else {
                g.setColor(0x000000);
            }
        }
        
        if(timeLeft==0){
            s = "Game Over ! ";
            g.drawString(s, 0, 0, Graphics.TOP | Graphics.LEFT);
            g.setColor(0x00ff00);
        }
        if(timeLeft!=0){
            g.drawString(s + timeLeft + " s", 0, 0, Graphics.TOP | Graphics.LEFT);
            g.setColor(0x000000);
        }
    }

    private void calculateCoupleX(int keyState) {
        if ((keyState & LEFT_PRESSED) != 0) {
            coupleX = Math.max(GAME_ORIGIN_X + sp.getWidth() / 2, coupleX - dx);
        } else if ((keyState & RIGHT_PRESSED) != 0) {
            coupleX = Math.min(GAME_ORIGIN_X + GAME_WIDTH - sp.getWidth() / 2, coupleX + dx);
        }
    }

    private void calculateCouple_X(int keyState) {
        if ((keyState & UP_PRESSED) != 0) {
            coupleY = Math.max(GAME_ORIGIN_Y + SECTION_HEIGHT + sp.getHeight(), coupleY - dy);
        } else if ((keyState & DOWN_PRESSED) != 0) {
            coupleY = Math.min(GAME_ORIGIN_Y + SECTION_HEIGHT + MAX_HEIGHT, coupleY + dy);
        }
    }

    private void calculateCoupleY(int keyState) {
        if (up) {
            if ((coupleY > (BASE - jumpHeight + coupleImg.getHeight()))) {
                coupleY -= dy;
            } else if (coupleY == (BASE - jumpHeight + coupleImg.getHeight())) {
                coupleY += dy;
                up = false;
            }
        } else {
            if (coupleY < BASE) {
                coupleY += dy;
            } else if (coupleY == BASE) {

                coupleY -= dy;
                up = true;
            }

        }
    }

    private void calculateCoupleY_1() {
        if (left) {
            if ((coupleX - (sp.getWidth()) / 2) > GAME_ORIGIN_X) {
                coupleX -= dx;
            } else if ((coupleX - (sp.getWidth() / 2)) == GAME_ORIGIN_X) {
                coupleY += dy;
                left = false;
            }
        } else {
            if ((coupleX + (sp.getWidth() / 2)) < (GAME_ORIGIN_X + GAME_WIDTH)) {
                coupleX += dy;
            } else if ((coupleX + (sp.getWidth() / 2)) == (GAME_ORIGIN_X + GAME_WIDTH)) {
                //int hyper = random.nextInt(MAX_HEIGHT + 1);

                //if(hyper > coupleImg.getHeight())
                //jumpHeight = hyper;
                coupleX -= dy;
                left = true;
            }

        }
    }

    private void buildGameScreen(Graphics g) {
        g.setColor(0x000000);
        g.drawRect(GAME_ORIGIN_X, GAME_ORIGIN_Y, GAME_WIDTH, GAME_HEIGHT);
        g.drawLine(GAME_ORIGIN_X, BASE, GAME_ORIGIN_X + GAME_WIDTH, BASE);
        g.drawLine(GAME_ORIGIN_X, BASE - MAX_HEIGHT, GAME_ORIGIN_X + GAME_WIDTH, BASE - MAX_HEIGHT);
        //background.paint(g);
    }

    private void createBackground() {
        try {
            backgroundImg = Image.createImage("/Images/BackGround.png");
            background = new TiledLayer(5, 5, backgroundImg, 32, 32);
            int[] cells = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
            for (int i = 0; i < cells.length; i++) {
                int column = i % 5;
                int row = (i - column) / 5;
                background.setCell(column, row, cells[i]);
            }
            background.setPosition(GAME_ORIGIN_X, GAME_ORIGIN_Y);
        } catch (IOException ex) {
        }
    }

    public Random getRandom() {
        return new Random();
    }

    public Sprite getCoupleSprite() {
        return sp;
    }

    public void showGameScore(Graphics g){
        g.setColor(0xffffff);
        g.fillRect(0, CENTER_Y-20, getWidth(), 40);
        g.setColor(0x000000);
        g.drawString("You hit "+car.getCarHits()+"cars.", CENTER_X, CENTER_Y, Graphics.HCENTER|Graphics.BASELINE);
        flushGraphics();
    }    
}
